<!--
 * @Author       : 梁嘉琳
 * @Date         : 2022-05-27 11:11:29
 * @LastEditors: liangjialin liangjialin@optfuture.cn
 * @LastEditTime: 2022-07-15 15:01:25
 * @FilePath     : \three\examples\couldGeometry.html
-->

<!-- 
	transformControls
	trackballcontrols
	dragControls
 -->

<!DOCTYPE html>
<html lang="zh">
  <head>
    <title>threejs学习</title>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"
    />
    <link rel="icon" href="../favicon.ico" />
    <link type="text/css" rel="stylesheet" href="../public/main.css" />
  </head>
  <body>
    <canvas id="fireflx"></canvas>
    <div style="position: fixed; top: 0">
      <label for="uploadFile1">node</label>
      <input type="file" id="uploadFile1" />
      <label for="uploadFile2">indices</label>
      <input type="file" id="uploadFile2" />
      <label for="uploadFile3">dispVetor</label>
      <input type="file" id="uploadFile3" />
      <label for="uploadFile3">选择位移</label>
      <select name="aa" id="select">
        <option value="x">x</option>
        <option value="y">y</option>
        <option value="z">z</option>
        <!-- <option value="abs">abs</option> -->
      </select>
    </div>

    <script type="importmap">
      {
        "imports": {
          "three": "../node_modules/three/build/three.module.js",
          "three/": "../node_modules/three/",
          "public/": "../public/"
        }
      }
    </script>

    <script type="module">
      import * as THREE from "three";
      import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
      import { resizeRendererToDisplaySize } from "public/resizeHandle.js";
      import { Lut } from "three/examples/jsm/math/Lut.js";
      const input1 = document.getElementById("uploadFile1");
      const input2 = document.getElementById("uploadFile2");
      const input3 = document.getElementById("uploadFile3");
      input1.addEventListener("change", readLocalFile1);
      input2.addEventListener("change", readLocalFile2);
      input3.addEventListener("change", readLocalFile3);

      let node, elements, dispVector;
      function readLocalFile1(e) {
        const localFile = e.target.files[0];
        var reader = new FileReader();
        reader.readAsText(localFile);
        reader.onload = function () {
          const arrs = [];
          const arr = this.result.split("\r\n");
          arr.forEach((v) => {
            const ar = v.split(" ");
            if (ar.length > 1)
              arrs.push(Number(ar[1]), Number(ar[2]), Number(ar[3]));
          });
          // console.log(arrs);
          node = arrs;
          if (node && elements && dispVector) {
            init();
            animate();
          }
        };
      }
      function readLocalFile2(e) {
        const localFile = e.target.files[0];
        var reader = new FileReader();
        reader.readAsText(localFile);
        reader.onload = function () {
          const arrs = [];
          const arr = this.result.split("\r\n");
          arr.forEach((v) => {
            const ar = v.split(" ");
            arrs.push([
              Number(ar[1]) - 1,
              Number(ar[2]) - 1,
              Number(ar[3]) - 1,
              Number(ar[4]) - 1,
            ]);
          });
          // console.log(arrs);
          elements = arrs;
          if (node && elements && dispVector) {
            init();
            animate();
          }
        };
      }
      function readLocalFile3(e) {
        const localFile = e.target.files[0];
        var reader = new FileReader();
        reader.readAsArrayBuffer(localFile);
        reader.onload = function () {
          dispVector = new Float64Array(this.result);
          console.log(dispVector);
          if (node && elements && dispVector) {
            init();
            animate();
          }
        };
      }

      const select = document.querySelector("select");
      select.addEventListener("change", init);

      const canvas = document.querySelector("#fireflx");
      let perpCamera, orthoCamera, renderer, lut;
      let mesh, sprite;
      let scene, uiScene, params;

      const h = window.innerHeight;
      const w = window.innerWidth;
      const k = w / h;

      function init(e) {
        const select = !!e ? e.target.value : "x";
        lut = new Lut();
        uiScene = new THREE.Scene();

        scene = new THREE.Scene();
        scene.background = new THREE.Color(0xffffff);

        renderer = new THREE.WebGLRenderer({ canvas, antialias: true });
        renderer.autoClear = false;

        perpCamera = new THREE.PerspectiveCamera(60, k, 0.1, 1000);
        perpCamera.position.set(0, 0, 100);

        const pointLight = new THREE.PointLight(0xffffff, 1);
        perpCamera.add(pointLight);
        scene.add(perpCamera);

        // orthoCamera = new THREE.OrthographicCamera(-1, 1, 1, -1, 1, 2);
        orthoCamera = new THREE.OrthographicCamera(
          w / -2,
          w / 2,
          h / 2,
          h / -2,
          1,
          1000
        );
        orthoCamera.position.set(0.5, 0, 1);

        const gradual = document.createElement("canvas");
        gradual.width = 400;
        gradual.height = 529;
        const ctx = gradual.getContext("2d");
        const gradient = ctx.createLinearGradient(0, 0, 0, 500);
        gradient.addColorStop(0, "#0000FF");
        gradient.addColorStop(0.25, "#00FFFF");
        gradient.addColorStop(0.5, "#00FF00");
        gradient.addColorStop(0.75, "#FFFF00");
        gradient.addColorStop(1, "#FF0000");

        ctx.fillStyle = gradient;
        ctx.fillRect(0, 10, 30, 500);
        ctx.fillStyle = "#1a1a1a";
        ctx.font = "12px serif";
        for (let i = 0; i < 13; i++) {
          const y = i * (500 / 12) + 15;
          ctx.fillText("- 2.31000e-20" + i, 30, i === 12 ? y - 1 : y);
        }
        // document.body.appendChild(gradual);

        let texture = new THREE.Texture(gradual);
        sprite = new THREE.Sprite(
          new THREE.SpriteMaterial({ map: texture, transparent: true })
        );
        sprite.scale.set(600, 600, 1);

        // sprite.position.x = 200;
        // sprite.scale.x = 0.15;

        // sprite = new THREE.Sprite(
        // 	new THREE.SpriteMaterial({
        // 		map: new THREE.CanvasTexture(lut.createCanvas()),
        // 	})
        // );
        // sprite.scale.x = 0.125;
        // sprite.scale.y = 0.125;
        // sprite.scale.z = 100;
        // sprite.position.set(145, 220, -135);
        uiScene.add(sprite);

        let geometry = new THREE.BufferGeometry();
        geometry.setAttribute(
          "position",
          new THREE.BufferAttribute(new Float32Array(node), 3)
        );

        const indices = [];
        const patchNodes = [0, 2, 1, 0, 1, 3, 1, 2, 3, 0, 3, 2];
        for (let j = 0; j < elements.length; j++) {
          const cur = elements[j];
          for (let i = 0; i < patchNodes.length; i++) {
            indices.push(cur[patchNodes[i]]);
          }
        }
        geometry.setIndex(indices);

        geometry.center();
        geometry.computeVertexNormals();
        // geometry.

        const colors = [];
        for (let i = 0, n = geometry.attributes.position.count; i < n; ++i) {
          colors.push(1, 1, 1);
        }

        geometry.setAttribute(
          "color",
          new THREE.Float32BufferAttribute(colors, 3)
        );

        lut.setColorMap("rainbow");
        const dispVector_array = Array.from(dispVector);
        const disp1 = [],
          disp2 = [],
          disp3 = [];
        for (let i = 0; i < 5927; i++) {
          disp1[i] = dispVector_array[3 * i];
          disp2[i] = dispVector_array[3 * i + 1];
          disp3[i] = dispVector_array[3 * i + 2];
        }
        let ma = Math.max(...disp1),
          mi = Math.min(...disp1),
          disps = disp1;
        console.log(ma, mi);

        if (select === "x") {
          ma = Math.max(...disp1);
          mi = Math.min(...disp1);
          disps = disp1;
        } else if (select === "y") {
          ma = Math.max(...disp2);
          mi = Math.min(...disp2);
          console.log(ma, mi);
          disps = disp2;
        } else if (select === "z") {
          ma = Math.max(...disp3);
          mi = Math.min(...disp3);
          console.log(ma, mi);
          disps = disp3;
        }
        lut.setMax(ma);
        lut.setMin(mi);
        const colorValve = geometry.attributes.color;
        // const ratio = ma / 12;
        const n = geometry.attributes.position.count;

        const canvasColor = lut.createCanvas();
        canvasColor.width = 200;
        canvasColor.height = 500;

        console.log(canvasColor);
        document.body.appendChild(canvasColor);

        for (let i = 0; i < n; i++) {
          // const cv = Math.trunc(disps[i] / ratio);
          // const color = lut.getColor(cv);
          const color = lut.getColor(disps[i]);
          if (color === undefined) {
            console.log("Unable to determine color for value:", colorValue);
          } else {
            colorValve.setXYZ(i, color.r, color.g, color.b);
          }
        }
        colorValve.needsUpdate = true;
        const map = sprite.material.map;
        lut.updateCanvas(map.image);
        map.needsUpdate = true;

        const material = new THREE.MeshBasicMaterial({ vertexColors: true });

        const wireframeMaterial = new THREE.MeshBasicMaterial({
          color: 0x000000,
          wireframe: true,
          transparent: true,
        });

        let wireframe = new THREE.Mesh(geometry, wireframeMaterial);

        mesh = new THREE.Mesh(geometry, material);
        mesh.add(wireframe);
        scene.add(mesh);
        const controls = new OrbitControls(perpCamera, renderer.domElement);
      }
      //HSL:Hue, Saturation, Lightness:色相 饱和度 亮度
      function animate() {
        renderer.clear();
        if (resizeRendererToDisplaySize(renderer)) {
          const canvas = renderer.domElement;
          perpCamera.aspect = canvas.clientWidth / canvas.clientHeight;
          perpCamera.updateProjectionMatrix();
        }
        renderer.render(scene, perpCamera);
        renderer.render(uiScene, orthoCamera);
        requestAnimationFrame(animate);
      }
    </script>
  </body>
</html>
